<?php

/*
 * Copyright 2008 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#namespace tehframework\testing\yaymockery;

class Mockery extends Yay_Mockery
{
	/**
	 * @var array
	 */
	private $expectations = array();
	
	/**
	 * @var array
	 */
	private $unexpected = array();
	
	/**
	 * @param Yay_ExpectationProvider $expectationProvider
	 */
	public function checking(Yay_ExpectationProvider $expectationProvider)
	{
		$this->expectations[] = $expectationProvider;
	}
	
	/**
	 * @param Yay_Invocation $invocation
	 * @return unknown
	 */
	public function &handleInvocation(Yay_Invocation $invocation)
	{
		$result   = null;
		$expected = false;
		
		foreach ($this->expectations as $expectations)
		{
			if ($expectations instanceof Yay_ExpectationProvider)
			{
				$expectations = $expectations->getExpectations();
			}
			
			foreach ($expectations as $expectation)
			{
				if ($expectation->isExpected($invocation))
				{
					$expected = true;
					$action   = $expectation->getAction($invocation);
					
					if ($action)
					{
						$result =& $action->invoke($invocation);
					}
					
					break;
				}
			}
		}
		
		if (!$expected)
		{
			$this->unexpected[] = $invocation;
		}
		
		return $result;
	}

	public function assertIsSatisfied()
	{
		$description = new Yay_SimpleDescription();
		$satisfied = true;
		
		foreach ($this->unexpected as $invocation)
		{
			$description->appendText('Unexpected invocation');
			$invocation->describeTo($description);
			$description->appendText(PHP_EOL);
			
			$satisfied = false;
		}
		
		if (!$satisfied)
		{
			$description->appendText(PHP_EOL);
		}
		
		foreach ($this->expectations as $expectationProvider)
		{
			foreach ($expectationProvider->getExpectations() as $expectation)
			{
				$expectation->describeTo($description);
				$description->appendText(PHP_EOL);
				
				if (!$expectation->isSatisfied())
				{
					$satisfied = false;
				}
			}
		}
		
		if (!$satisfied)
		{
			throw new Yay_NotSatisfiedException($description->toString());
		}
	}
}